#define _CRT_SECURE_NO_WARNINGS
#include"queue.h"

void queue_init(queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void queue_push(queue* pq, queue_data_type x)
{
	assert(pq);
	q_node* newnode = (q_node*)malloc(sizeof(q_node));
	if (newnode == NULL)
	{
		perror("EXPANSION");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

void queue_pop(queue* pq)
{
	assert(pq && !queue_empty(pq));
	q_node* tmp = pq->head->next;
	if (pq->head == pq->tail)
	{
		pq->tail = tmp;
	}
	free(pq->head);
	pq->head = tmp;
}

void queue_destory(queue* pq)
{
	assert(pq);
	q_node* cur = pq->head;
	while (cur)
	{
		q_node* tmp = cur->next;
		free(cur);
		cur = tmp;
	}
	pq->head = pq->tail = NULL;
}

int queue_size(queue* pq)
{
	assert(pq);
	q_node* cur = pq->head;
	int n = 0;
	while (cur)
	{
		n++;
		cur = cur->next;
	}
	return n;
}

bool queue_empty(queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

queue_data_type queue_front(queue* pq)
{
	assert(pq && !queue_empty(pq));
	return pq->head->data;
}

queue_data_type queue_back(queue* pq)
{
	assert(pq && !queue_empty(pq));
	return pq->tail->data;
}
